// Copyright  2004-2008 Backplane Ltd.
//
// This file is part of Ubiquity formsPlayer
//
// Ubiquity formsPlayer is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3 of the License, or (at your
// option) any later version.
//
// Ubiquity formsPlayer is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// You should have received a copy of the GNU General Public License
// along with Ubiquity formsPlayer If not, see <http://www.gnu.org/licenses/>.
//	
//
//   Purpose: Implementation of CMessageDialog.
//   $Id$


#include "stdafx.h"
#include "MessageDialog.h"

/////////////////////////////////////////////////////////////////////////////
// CMessageDialog


DWORD WINAPI setCloseTimeout(LPVOID pvdDlg)
{
	CMessageDialog* pDlg = static_cast<CMessageDialog*>(pvdDlg);
	if(pDlg->m_lTimeoutMS > -1)
	{
		pDlg->Create(::GetActiveWindow());
	
		pDlg->m_hTimer = CreateWaitableTimer(
		  NULL,
		  FALSE,                       // reset type
		  "theTimer"                      // object name
		);
		LARGE_INTEGER liDueTime;
		liDueTime.QuadPart=(-10000 * pDlg->m_lTimeoutMS);
		
		 SetWaitableTimer(pDlg->m_hTimer, &liDueTime, 0, NULL, NULL, 0);


		 while(!pDlg->m_bShutDown)
		 {
			 bool bBroken = false;
		        MSG msg ; 
		        while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 
				{ 
					// If it's a quit message, we're out of here.
					if (msg.message == WM_QUIT)  
					{
						bBroken = true;
						break; 
					}
					else
						// Otherwise, dispatch the message.
						::DispatchMessage(&msg); 
				} // End of PeekMessage while loop.
			if(bBroken || pDlg->m_bShutDown)
				break;

			 DWORD result = MsgWaitForMultipleObjects(
			  1,
			  &pDlg->m_hTimer, // object-handle array
			  FALSE,
			  1000,  // time-out interval
			  QS_ALLEVENTS
			);
			
			if (result == (WAIT_OBJECT_0 + 1))
			{
				// New messages have arrived. 
				// Continue to the top of the always while loop to 
				// dispatch them and resume waiting.
				continue;
			} 
			else if(result == WAIT_TIMEOUT)
			{
				continue;
			}
			else 
			{ 
				break; 
			} // End of else clause.

		 }

		 if(pDlg->m_hWnd)
		{
			BOOL bGone = pDlg->DestroyWindow();
		}
	}
	
	ExitThread(pDlg->m_IDThread);
	return 0;
}
LRESULT CMessageDialog::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
	HWND wBrowser = GetDlgItem(IDC_MessageBrowser);
	if(wBrowser)
	{
		//set the size of the browser,
		RECT Rect;
		GetClientRect(&Rect);
		::SetWindowPos(wBrowser,HWND_TOP,Rect.left,Rect.top,Rect.right,Rect.bottom,0);

		//navigate or write the message
		IUnknown *pUnk = 0;
		HRESULT hr = AtlAxGetControl(wBrowser,&pUnk);
		if(SUCCEEDED(hr))
		{
			CComQIPtr<IWebBrowser2> pBrowser = pUnk;
			if(pBrowser)
			{
				VARIANT vt;
				vt.vt = VT_NULL;
				if(m_bNavigate)
					pBrowser->Navigate(m_sText.m_str,&vt,&vt,&vt,&vt);
				else
				{
					CComBSTR sAboutBlank(L"about:blank");
					pBrowser->Navigate(sAboutBlank,&vt,&vt,&vt,&vt);
					CComPtr<IDispatch> pDisp;			
					hr = pBrowser->get_Document(&pDisp);
					if(SUCCEEDED(hr))
					{
						CComQIPtr<IHTMLDocument2> pDoc2(pDisp);
						if(pDoc2)
						{
							// write to the document
							//lifted code from MSDN
								VARIANT *param;
								SAFEARRAY *sfArray;

								// Creates a new one-dimensional array
								sfArray = SafeArrayCreateVector(VT_VARIANT, 0, 1);

								SafeArrayAccessData(sfArray,(LPVOID*) & param);
								param->vt = VT_BSTR;
								param->bstrVal = m_sText.Copy();
								SafeArrayUnaccessData(sfArray);
								pDoc2->write(sfArray);
								::SysFreeString(param->bstrVal);

								//END: lifted code.
							//close it to allow documentReady to be called
							pDoc2->close();
						}
					}
				}
			}
		}
		::safeRelease(pUnk);
	}
	
	return 1;  // Let the system set the focus
}
/*
LRESULT CMessageDialog::OnOK(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
{
	if(m_bIsModal)
	{
		EndDialog(wID);
	}
	else
	{
		if(m_hWnd)
			DestroyWindow();
		m_pXForms->onCloseDialog(this);
	}
	return 0;
}
*/

LRESULT CMessageDialog::OnCancel(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
{
	if(m_bIsModal)
	{
		EndDialog(wID);
	}
	else
	{
		if(m_hWnd)
		{
			DestroyWindow();
		}
		m_pXForms->onCloseDialog(this);
	}
	
	return 0;
}
LRESULT CMessageDialog::OnShowWindow(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
	// MS: Call DefWindowProc if necessary.
	return 0;
}
LRESULT CMessageDialog::OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
	
	HWND wBrowser = GetDlgItem(IDC_MessageBrowser);
	if(wBrowser)
	{
		RECT Rect;
		GetClientRect(&Rect);
		::SetWindowPos(wBrowser,HWND_TOP,Rect.left,Rect.top,Rect.right,Rect.bottom,0);
	}
	
	return 0;
}
CMessageDialog::CMessageDialog()
		:m_hTimer(0)
		,m_IDThread(0)
		,m_bShutDown(false)
		,m_lTimeoutMS(0)
		,m_bNavigate(false)
		,m_bIsModal(false)
		,m_pXForms(0)
	{
	}

CMessageDialog::CMessageDialog(BSTR sText,bool bNavigate,bool bIsModal,CXFormsXFormsElement* pForm, long lTimeoutMS)
		:m_sText(sText)
		,m_bNavigate(bNavigate)
		,m_bIsModal(bIsModal)
		,m_pXForms(pForm)
		,m_lTimeoutMS(lTimeoutMS)
		,m_bShutDown(false)
		,m_hTimer(0)
{
	if(m_bIsModal)
		DoModal();
	else if(m_lTimeoutMS==-1)
		Create(::GetActiveWindow());
	else
	{
			CreateThread(NULL, // no security attributes 
			0,                           // use default stack size 
			(LPTHREAD_START_ROUTINE) setCloseTimeout, // thread function 
			this,                    // no thread function argument 
			0,                       // use default creation flags 
			&m_IDThread);              
	}
		


}
CMessageDialog::~CMessageDialog()
{
	if(!m_bIsModal && m_hWnd)
	{
		DestroyWindow();
	}
	if(m_hTimer)
	{
		//Set shutDown flag.  The timer thread 
		//	will exit and close the window when it
		//	sees that this is true.
		m_bShutDown = true;
		//wait for the window to close.
		//Calling DestroyWindow here will do nothing,
		// as it can only be destroyed by its own thread.
		// We just have to wait until the timer thread exits.
		//while(m_hWnd);
		 while(m_hWnd)
		 {
			 bool bBroken = false;
		        MSG msg ; 
		        while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 
				{ 
					// If it's a quit message, we're out of here.
					if (msg.message == WM_QUIT)  
					{
						bBroken = true;
						break; 
					}
					else
						// Otherwise, dispatch the message.
						::DispatchMessage(&msg); 
				} // End of PeekMessage while loop.
			if(bBroken)
				break;

			 DWORD result = MsgWaitForMultipleObjects(
			  1,
			  0, // object-handle array
			  FALSE,
			  1000,  // time-out interval
			  QS_ALLEVENTS
			);
		 }
	}
		

}
